package com.conf4j.kit;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashSet;

import com.conf4j.Conf;
import com.conf4j.ConfigManager;
import com.conf4j.Prop;
import com.conf4j.annotation.Config;

/**
 * 配置工具类
 * 
 * @author dingnate
 *
 */
public final class ConfKit {
	public static void handler(Class<?> clazz) throws Exception, SecurityException {
		Config annotation = clazz.getAnnotation(Config.class);
		if (annotation == null || !Conf.class.isAssignableFrom(clazz))
			return;
		String file = annotation.file();
		if (StrKit.isBlank(file))
			return;

		Prop prop = new Prop(file);
		Field meField = clazz.getDeclaredField(Conf.SINGLETON_NAME);
		meField.setAccessible(true);
		Object me = meField.get(null);
		if (me == null) {
			me = clazz.newInstance();
			meField.set(null, me);
		}
		ConfigManager.putProperties(prop.getProperties());
		ConfigManager.addConfig(me);
		String prefix = annotation.prefix();
		Collection<Method> setMethods = getClassSetMethods(clazz);
		for (Method method : setMethods) {
			String keyByMethod = getKeyByMethod(prefix, method);
			ConfigManager.putMethod(keyByMethod, method);
			String value = prop.get(keyByMethod);
			if (StrKit.isNotBlank(value)) {
				Object val = ValueKit.convert(value, method.getParameterTypes()[0]);
				method.invoke(me, val);
			}
		}
	}

	private static Collection<Method> getClassSetMethods(Class<?> clazz) {
		Method[] methods = clazz.getMethods();
		Collection<Method> setMethods = new HashSet<Method>();
		for (Method method : methods) {
			if (method.getName().startsWith("set") && method.getName().length() > 3
					&& method.getParameterTypes().length == 1) {
				setMethods.add(method);
			}
		}
		return setMethods;
	}

	private static String getKeyByMethod(String prefix, Method method) {
		String key = StrKit.firstCharToLowerCase(method.getName().substring(3));
		if (StrKit.isNotBlank(prefix)) {
			key = prefix.trim() + "." + key;
		}
		return key;
	}
	
	/**
	 * 获取文件版本
	 * 
	 * @param file
	 * @return
	 */
	public static String getVersion(File file) {
		return "time:" + file.lastModified();
	}
}
